using Godot;

// 标记为全局脚本类
[GlobalClass]
public partial class Enemy : CharacterBody3D
{
    // 最大生命上限
    [Export] public float ExMaxHitpoints = 100f;

    // 导航代理的速度
    [Export] public float ExSpeed = 3.0f;

    // 敌人激怒探测范围
    [Export] public float ExAggroRange = 10f;

    // 敌人的攻击范围
    [Export] public float ExAttackRange = 1.5f;

    [Export] public float ExAttackDamage = 20f; //敌人伤害

    private NavigationAgent3D _navigationAgent3D;

    private RoboRampage.Player.Player _player;

    // private AnimationPlayer _animationPlayer;
    private AnimationTree _animationTree;
    // 动画状态机的核心类，主要用于动态管理动画状态之间的切换、播放行为和状态查询
    private AnimationNodeStateMachinePlayback _playback;

    private float _currHitpoints; // 私有字段存储实际值

    // 当前生命值
    public float CurrHitpoints
    {
        get => _currHitpoints;
        set
        {
            _currHitpoints = value;
            // 生命值掉完了就删除组件
            if (value <= 0) QueueFree();
            _provoked = true;
        }
    }

    // 是否被激怒
    private bool _provoked = false;

    public override void _Ready()
    {
        CurrHitpoints = ExMaxHitpoints;
        // 获取导航代理节点
        _navigationAgent3D = (NavigationAgent3D)GetNode("NavigationAgent3D");
        // 获取动画播放器节点
        // _animationPlayer = (AnimationPlayer)GetNode("AnimationPlayer");
        _animationTree = (AnimationTree)GetNode("AnimationTree");
        _playback = _animationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>();
        // 获取玩家节点
        _player = (RoboRampage.Player.Player)GetTree().GetFirstNodeInGroup("player");
    }

    public override void _Process(double delta)
    {
        if (_provoked)
        {
            // 设置导航代理的目标位置为玩家的全局位置
            _navigationAgent3D.TargetPosition = _player.GlobalPosition;
        }
    }

    public override void _PhysicsProcess(double delta)
    {
        // 获取下一个路径位置
        Vector3 nextPosition = _navigationAgent3D.GetNextPathPosition();
        // 获取敌人到玩家位置的距离
        float distance = GlobalPosition.DistanceTo(_player.GlobalPosition);

        // 如果距离小于等于攻击范围，则设置_provoked为true
        _provoked = distance <= ExAggroRange;

        if (_provoked && distance <= ExAttackRange)
        {
            // GD.Print("敌人发起攻击！");
            // _animationPlayer.Play("Attack");
            _playback.Travel("Attack");
        }

        Vector3 velocity = Velocity;

        // Add the gravity.
        if (!IsOnFloor())
        {
            velocity += GetGravity() * (float)delta;
        }

        Vector3 direction = GlobalPosition.DirectionTo(nextPosition);
        if (direction != Vector3.Zero)
        {
            LookAtTarget(direction);
            velocity.X = direction.X * ExSpeed;
            velocity.Z = direction.Z * ExSpeed;
        }
        else
        {
            velocity.X = Mathf.MoveToward(Velocity.X, 0, ExSpeed);
            velocity.Z = Mathf.MoveToward(Velocity.Z, 0, ExSpeed);
        }

        Velocity = velocity;
        MoveAndSlide();
    }

    // 敌人看向玩家
    public void LookAtTarget(Vector3 direction)
    {
        // 等价于
        // var adjustedDirection = new Vector3(direction.X, 0, direction.Z);
        var adjustedDirection = direction with { Y = 0 };
        LookAt(GlobalPosition + adjustedDirection, Vector3.Up, true);
    }


    public void Attack()
    {
        _player.CurrHitpoints -= ExAttackDamage;
    }
}